package com.jxtpro.generator;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import javax.sql.DataSource;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.dialect.Dialect;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.generator.MetaBuilder;
import com.jfinal.plugin.activerecord.generator.TableMeta;
import com.jfinal.plugin.activerecord.generator.TypeMapping;
import com.jfinal.template.Engine;
import com.jfinal.template.Template;
import com.jfinal.template.source.ClassPathSourceFactory;

public abstract class AbstractGenerator implements Generator{
	
		private String[] templates = { "service.html"};
		private String[] paths = {"service"};
		private String[] fileNames = {"Service.java"};
		private Map<String,String> generator = read("generator");
		private String fileSeparator = System.getProperty("file.separator");
		private String projectPackage = generator.get("projectPackage");
		private String daoPackage = generator.get("daoPackage");
		private Dialect dialect = new MysqlDialect();
		private String removedTableNamePrefixes = "security_";
		private MetaBuilder metaBuilder = null;
		private String[] excludedTables;
		private TypeMapping typeMapping =  new TypeMapping();
		private ClassPathSourceFactory clapathFactory = new ClassPathSourceFactory();
		
		
		
		
		public String[] getTemplates() {
			return templates;
		}

		public void setTemplates(String[] templates) {
			this.templates = templates;
		}

		public String[] getPaths() {
			return paths;
		}

		public void setPaths(String[] paths) {
			this.paths = paths;
		}

		public String[] getFileNames() {
			return fileNames;
		}

		public void setFileNames(String[] fileNames) {
			this.fileNames = fileNames;
		}

		public String getProjectPackage() {
			return projectPackage;
		}

		public void setProjectPackage(String projectPackage) {
			this.projectPackage = projectPackage;
		}

		public String getDaoPackage() {
			return daoPackage;
		}

		public void setDaoPackage(String daoPackage) {
			this.daoPackage = daoPackage;
		}

		public Dialect getDialect() {
			return dialect;
		}

		public void setDialect(Dialect dialect) {
			this.dialect = dialect;
		}

		public String getRemovedTableNamePrefixes() {
			return removedTableNamePrefixes;
		}

		public void setRemovedTableNamePrefixes(String removedTableNamePrefixes) {
			this.removedTableNamePrefixes = removedTableNamePrefixes;
		}

		public String[] getExcludedTables() {
			return excludedTables;
		}

		public void setExcludedTables(String[] excludedTables) {
			this.excludedTables = excludedTables;
		}

		public TypeMapping getTypeMapping() {
			return typeMapping;
		}

		public void setTypeMapping(TypeMapping typeMapping) {
			this.typeMapping = typeMapping;
		}

		public MetaBuilder setDataSource(DataSource dataSource){
				metaBuilder = new MetaBuilder(dataSource);
			  	metaBuilder.setDialect(dialect);
	            metaBuilder.setTypeMapping(typeMapping);
	            metaBuilder.addExcludedTable(excludedTables);
	            metaBuilder.setRemovedTableNamePrefixes(removedTableNamePrefixes);
			return metaBuilder;
		}
	
	   public void gen2M2C(DataSource dataSource) throws Exception{
			if(dataSource != null){
	     	    MetaBuilder metaBuilder = setDataSource(dataSource);
	            List<TableMeta> tableMetas = metaBuilder.build();
	            Map<String,Object> content = new HashMap<String,Object>();
	            for(TableMeta table : tableMetas){
	            	String claLowName = StrKit.firstCharToLowerCase(StrKit.toCamelCase(table.modelName));
	            	GeneratorMeta gm =new GeneratorMeta(table.modelName,claLowName,projectPackage,table.columnMetas);
	            	gm.daoPackage = daoPackage;
	            	gm.remarks = table.remarks;
	            	content.put("meta", gm);
	         	   for(int i = 0; i < templates.length; i ++){
	         		   Template template = 	Engine.use().setEncoding("utf-8").setSourceFactory(clapathFactory)
	         				   .getTemplate(templates[i]);
	         		   
	         		   String fileName = toOutPath(paths[i]) + table.modelName
	         		   + fileNames[i];
						writeFiles(template, content, fileName);
	         		   System.out.println("write File: " + fileName);
	         	   }
	            }
	            System.out.println("--- ok 刷新项目 ---");
			}

	    }
	   
	   public String toOutPath(String out){
		    String basePath = Class.class.getClass().getResource("/").getPath();
	 		String pathStr = out;
				String outPath = basePath + "out/"
						+ projectPackage.replace(".", fileSeparator) + "/"
						+ pathStr + "/";

				File file = new File(outPath);
				if (!file.exists()) {
					file.mkdirs();
				}
			return outPath;	
	   }
	   
	   public void gen2C2M(DataSource dataSource) throws Exception{
		   
	   }
	   
	   public Map<String,String> read(String pf){
	    	ResourceBundle rb = ResourceBundle.getBundle(pf);
			Map<String, String> map = new HashMap<String, String>();
			Enumeration<String> enu = rb.getKeys();
			while (enu.hasMoreElements()) {
				String key = enu.nextElement();
				String value = rb.getString(key);
				map.put(key, value);
			}
			return map;
	    }

	   
		private  void writeFiles(Template template, Map<String,Object> context,
				String fileName) throws IOException {
			FileWriter fileWriter = new FileWriter(fileName, false);
			template.render(context, fileWriter);
			fileWriter.close();
		}
		
}
